﻿package Util
{
	import flash.utils.ByteArray;
	
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.net.URLRequestMethod;
	import flash.net.URLLoaderDataFormat;
	
	import flash.events.Event;
	import flash.events.EventDispatcher;
	
	import json.JSON;
	
	/**
	 * PHP 远程调用类
	 */
	public class SecurityBinaryRemoting implements IRemoting
	{
		public static const ERROR_NO_SERVICE:int = -101;
		public static const ERROR_NO_FUNCTION:int = -102;
		public static const ERROR_SECURITY_REQUEST:int = -103;
		
		public static const SUCCESS:int = 1;
		
		public static const REQUSET_TYPE_1:int = 0;
		public static const REQUSET_TYPE_2:int = 1;
		
		private var _url:String;
		private var _path:String;
		
		/**
		 * 远程调用
		 * 
		 * @param String url
		 * @param String path
		 */
		public function SecurityBinaryRemoting(url:String, path:String)
		{
			_url = url;
			_path = path;
		}
		
		/**
		 * 更改远程调用包
		 * @param String path
		 */
		public function setPath(path:String)
		{
			_path = path;
		}
		
		public function decode(str:String, rand:String):String
		{
			return Util.MD5.calculate(rand) + Util.MD5.calculate(str);
		}
		
		public function getHash() {
			var date:Date = new Date();
			
			return Util.MD5.calculate(date.toDateString());
		}
		
		/**
		 * 字节流远程调用
		 * 
		 * @param String funcname
		 * @param Array params
		 * @param Function callback
		 */
		public function RemotCall(funcname:String, params:Array, callback:Function)
		{
			var hash:String = getHash();
			var arrPost:Array = new Array();
			arrPost.push(REQUSET_TYPE_1);
			arrPost.push(hash);
			
			var strPost:String = JSON.encode(arrPost);
			
			var binaryPost:ByteArray = new ByteArray();
			binaryPost.writeUTF(strPost);
			binaryPost.compress();
			
			var request:URLRequest = new URLRequest(_url + "?" + Math.random());
			request.contentType = "file";
			request.method = URLRequestMethod.POST;
			request.data = binaryPost;
			
			var loader:URLLoader = new URLLoader();
			loader.dataFormat = URLLoaderDataFormat.BINARY;
			loader.load(request);
			
			loader.addEventListener(
				Event.COMPLETE, 
				function(event:Event):void
				{
					var data:ByteArray = (event.currentTarget.data as ByteArray);
					data.uncompress();
					
					var ret:Object = JSON.decode(data.toString());
					var key = ret[0];
					
					var arrPost:Array = new Array();
					arrPost.push(REQUSET_TYPE_2);
					arrPost.push(_path);
					arrPost.push(funcname);
					arrPost.push(JSON.encode(params));
					arrPost.push(hash);
					arrPost.push(key);
					
					var strPost:String = JSON.encode(arrPost);
					
					var binaryPost:ByteArray = new ByteArray();
					binaryPost.writeUTF(strPost);
					binaryPost.compress();
					
					var request:URLRequest = new URLRequest(_url + "?" + Math.random());
					request.contentType = "file";
					request.method = URLRequestMethod.POST;
					request.data = binaryPost;
					
					var loader:URLLoader = new URLLoader();
					loader.dataFormat = URLLoaderDataFormat.BINARY;
					loader.load(request);
					
					loader.addEventListener(
						Event.COMPLETE, 
						function(event:Event):void
						{
							var data:ByteArray = (event.currentTarget.data as ByteArray);
							data.uncompress();
							
							var ret:Object = JSON.decode(data.toString());
							switch (ret[0]) 
							{
								case SUCCESS:
								{
									callback(ret[1]);
									break;
								}
								case ERROR_NO_SERVICE:
								{
									throw new RemotingError('错误的服务名称', ERROR_NO_SERVICE, _path);
									break;
								}
								case ERROR_NO_FUNCTION:
								{
									throw new RemotingError('错误的方法名称', ERROR_NO_FUNCTION, funcname);
									break;
								} 
								case ERROR_SECURITY_REQUEST:
								{
									throw new RemotingError('错误的请求', ERROR_SECURITY_REQUEST, '');
									break;
								} 
							}
						}
					);
				}
			);
		}
	}
}